package com.main.organizationandplatformmanagement.domain.organization.service;

import com.main.common.base.base.BaseAssemblerFactory;
import com.main.common.base.resp.RespBody;
import com.main.organizationandplatformmanagement.application.service.OrganizationService;
import com.main.organizationandplatformmanagement.domain.organization.entity.Organization;
import com.main.organizationandplatformmanagement.domain.organization.entity.OrganizationModel;
import com.main.organizationandplatformmanagement.domain.organization.entity.OrganizationModelAtomType;
import com.main.organizationandplatformmanagement.domain.organization.entity.OrganizationModelAtoms;
import com.main.organizationandplatformmanagement.domain.organization.repository.OrganizationModelAtomTypeRepository;
import com.main.organizationandplatformmanagement.domain.organization.repository.OrganizationModelAtomsRepository;
import com.main.organizationandplatformmanagement.domain.organization.repository.OrganizationModelRepository;
import com.main.organizationandplatformmanagement.domain.organization.repository.OrganizationRepository;
import com.main.organizationandplatformmanagement.interfaces.assembler.OrganizationAssembler;
import com.main.organizationandplatformmanagement.interfaces.assembler.OrganizationModelAssembler;
import com.main.organizationandplatformmanagement.interfaces.assembler.OrganizationModelAtomTypeAssembler;
import com.main.organizationandplatformmanagement.interfaces.assembler.OrganizationModelAtomsAssembler;
import com.main.organizationandplatformmanagement.interfaces.dto.AddOrganizationDTO;
import com.main.organizationandplatformmanagement.interfaces.dto.AddOrganizationModelAtomTypeDTO;
import com.main.organizationandplatformmanagement.interfaces.dto.AddOrganizationModelAtomsDTO;
import com.main.organizationandplatformmanagement.interfaces.dto.AddOrganizationModelDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class OrganizationServiceImpl implements OrganizationService {
    @Resource
    private OrganizationRepository organizationRepository;
    @Resource
    private OrganizationModelAtomTypeRepository organizationModelAtomTypeRepository;
    @Resource
    private OrganizationModelAtomsRepository organizationModelAtomsRepository;
    @Resource
    private OrganizationModelRepository organizationModelRepository;
    @Resource
    private BaseAssemblerFactory baseAssemblerFactory;

    public RespBody<Organization> addOrganization(AddOrganizationDTO addOrganizationDTO) {
        OrganizationAssembler organizationAssembler = new OrganizationAssembler(baseAssemblerFactory);
        Organization organization = organizationAssembler.toEntity(addOrganizationDTO);
        organizationRepository.save(organization);
        return RespBody.ok(organization);
    }   
    public RespBody<OrganizationModelAtomType> addOrganizationModelAtomType(AddOrganizationModelAtomTypeDTO addOrganizationModelAtomTypeDTO) {
        OrganizationModelAtomTypeAssembler organizationModelAtomTypeAssembler = new OrganizationModelAtomTypeAssembler(baseAssemblerFactory);
        OrganizationModelAtomType organizationModelAtomType = organizationModelAtomTypeAssembler.toEntity(addOrganizationModelAtomTypeDTO);
        organizationModelAtomTypeRepository.save(organizationModelAtomType);
        return RespBody.ok(organizationModelAtomType);
    }
    public RespBody<OrganizationModelAtoms> addOrganizationModelAtoms(AddOrganizationModelAtomsDTO addOrganizationModelAtomsDTO) {
        OrganizationModelAtomsAssembler organizationModelAtomsAssembler = new OrganizationModelAtomsAssembler(baseAssemblerFactory);
        OrganizationModelAtoms organizationModelAtoms = organizationModelAtomsAssembler.toEntity(addOrganizationModelAtomsDTO);
        organizationModelAtomsRepository.save(organizationModelAtoms);
        OrganizationModelAtomType organizationModelAtomType = organizationModelAtomTypeRepository.getById(organizationModelAtoms.getTypeId());
        organizationModelAtoms.setOrganizationModelAtomType(organizationModelAtomType);
        return RespBody.ok(organizationModelAtoms);
    }
    public RespBody<OrganizationModel> addOrganizationModel(AddOrganizationModelDTO addOrganizationModelDTO) {
        OrganizationModelAssembler organizationModelAssembler = new OrganizationModelAssembler(baseAssemblerFactory);
        OrganizationModel organizationModel = organizationModelAssembler.toEntity(addOrganizationModelDTO);
        organizationModelRepository.save(organizationModel);
        Organization organization = organizationRepository.getById(organizationModel.getOrganizationId());
        organizationModel.setOrganization(organization);
        OrganizationModelAtoms organizationModelAtom = organizationModelAtomsRepository.getById(organizationModel.getAtomicId());
        OrganizationModelAtomType organizationModelAtomType = organizationModelAtomTypeRepository.getById(organizationModelAtom.getTypeId());
        organizationModelAtom.setOrganizationModelAtomType(organizationModelAtomType);
        organizationModel.setOrganizationModelAtom(organizationModelAtom);
        if(organizationModel.getParentAtomicId()!=0){
            OrganizationModelAtoms organizationModelParentAtom = organizationModelAtomsRepository.getById(organizationModel.getParentAtomicId());
            OrganizationModelAtomType organizationModelParentAtomType = organizationModelAtomTypeRepository.getById(organizationModelParentAtom.getTypeId());
            organizationModelParentAtom.setOrganizationModelAtomType(organizationModelParentAtomType);
            organizationModel.setOrganizationModelParentAtom(organizationModelParentAtom);
        }
        return RespBody.ok(organizationModel);
    }

    public RespBody<List<OrganizationModel>> getOrganizationModelById(Long id) {
        OrganizationModelAssembler organizationModelAssembler = new OrganizationModelAssembler(baseAssemblerFactory);
        List<OrganizationModel> organizationModelList = organizationModelRepository.getListByOrganizationId(id);
        List<OrganizationModel> organizationModelArrayList = new ArrayList<>();
        for(OrganizationModel organizationModel : organizationModelList){
            if(organizationModel!=null){
               Organization organization = organizationRepository.getById(organizationModel.getOrganizationId());
               organizationModel.setOrganization(organization);
               OrganizationModelAtoms organizationModelAtom = organizationModelAtomsRepository.getById(organizationModel.getAtomicId());
               if(organizationModelAtom!=null){
                   OrganizationModelAtomType organizationModelAtomType = organizationModelAtomTypeRepository.getById(organizationModelAtom.getTypeId());
                   organizationModelAtom.setOrganizationModelAtomType(organizationModelAtomType);
                   organizationModel.setOrganizationModelAtom(organizationModelAtom);
                   if(organizationModel.getParentAtomicId()!=0){
                       OrganizationModelAtoms organizationModelParentAtom = organizationModelAtomsRepository.getById(organizationModel.getParentAtomicId());
                       OrganizationModelAtomType organizationModelParentAtomType = organizationModelAtomTypeRepository.getById(organizationModelParentAtom.getTypeId());
                       organizationModelParentAtom.setOrganizationModelAtomType(organizationModelParentAtomType);
                       organizationModel.setOrganizationModelParentAtom(organizationModelParentAtom);
                   }
                   organizationModelArrayList.add(organizationModel);
               }
            }
        }
        return RespBody.ok(organizationModelArrayList);
    }
}
